// File: louvain.h
// -- community detection header file
//-----------------------------------------------------------------------------
// Community detection
// Based on the article "Fast unfolding of community hierarchies in large networks"
// Copyright (C) 2008 V. Blondel, J.-L. Guillaume, R. Lambiotte, E. Lefebvre
//
// This file is part of Louvain algorithm.
//
// Louvain algorithm is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Louvain algorithm is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with Louvain algorithm.  If not, see <http://www.gnu.org/licenses/>.
//-----------------------------------------------------------------------------
// Author   : E. Lefebvre, adapted by J.-L. Guillaume
// Email    : jean-loup.guillaume@lip6.fr
// Location : Paris, France
// Time	    : February 2008
//-----------------------------------------------------------------------------
// see readme.txt for more details

#ifndef LOUVAIN_H
#define LOUVAIN_H

#include <stdio.h>
#include <stdlib.h>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <map>
#include <vector>

#include "graph_binary.h"
#include "quality.h"
#include "MersenneTwister.h"

using namespace std;

class Louvain
{
   public:
    vector<long double> neigh_weight;
    vector<int> neigh_pos;
    int neigh_last;

    //Random number generator
    MTRand& mtrand;

    // number of pass for one level computation
    // if -1, compute as many pass as needed to increase quality
    int nb_pass;

    // a new pass is computed if the last one has generated an increase
    // better than eps_impr
    // if 0.0L even a minor increase is enough to go for one more pass
    long double eps_impr;

    // Quality functions used to compute communities
    Quality* qual;

    // constructors:
    // reads graph from file using graph constructor
    // type defined the weighted/unweighted status of the graph file
    Louvain(int nb_pass, long double eps_impr, Quality* q, MTRand& mtrand);

    // initiliazes the partition with something else than all nodes alone
    void init_partition(char* filename_part);

    // compute the set of neighboring communities of node
    // for each community, gives the number of links from node to comm
    void neigh_comm(int node);

    // displays the graph of communities as computed by one_level
    void partition2graph();

    // displays the current partition (with communities renumbered from 0 to k-1)
    void display_partition(vector<int>* level = NULL);

    // generates the binary graph of communities as computed by one_level
    GraphBin partition2graph_binary();

    // compute communities of the graph for one level
    // return true if some nodes have been moved
    bool one_level();
};

#endif // LOUVAIN_H
